package com.kdgc.energy.dmm.table;

import com.kdgc.energy.dmm.entity.EntityInfo;
import com.kdgc.energy.dmm.util.NameUtil;
import lombok.Getter;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.ColumnTypeImpl;
import org.apache.metamodel.schema.MutableColumn;
import org.apache.metamodel.schema.MutableTable;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 表
 *
 * @author xu.wenchang
 * @version 1.0 2022/04/16
 */
public class Table {
    @Getter
    private EntityInfo entityInfo;
    
    /**
     * 表
     */
    @Getter
    private MutableTable table;
    
    /**
     * 字段
     */
    private Map<String, MutableColumn> columnMap;
    
    @Getter
    private Field pkField;
    
    public Table(EntityInfo entityInfo) {
        this.entityInfo = entityInfo;
        String tableName = this.entityInfo.getTableName();
        this.table = new MutableTable(tableName);
        this.buildColumns();
    }
    
    public String getFieldByColumn(String column) {
        for (Map.Entry<String, MutableColumn> entry : columnMap.entrySet()) {
            if (entry.getValue()
                     .getName()
                     .equals(column)) {
                return entry.getKey();
            }
        }
        
        return null;
    }
    
    public MutableColumn getColumnByField(String fieldName) {
        return this.columnMap.get(fieldName);
    }
    
    public MutableColumn getColumn(String methodName) {
        return this.columnMap.get(NameUtil.methodName2FieldName(methodName));
    }
    
    private void buildColumns() {
        Map<String, EntityInfo.Tuple> map = this.entityInfo.getFieldColumnMap();
        this.columnMap = new HashMap<>();
        
        for (Map.Entry<String, EntityInfo.Tuple> entry : map.entrySet()) {
            EntityInfo.Tuple tuple = entry.getValue();
            ColumnType ct = ColumnTypeImpl.convertColumnType(tuple.getType());
            MutableColumn col = new MutableColumn(tuple.getColumnName(), ct, this.table);
            col.setPrimaryKey(tuple.isPk());
            this.columnMap.put(entry.getKey(), col);
            this.table.addColumn(col);
            
            if (tuple.isPk()) {
                try {
                    this.pkField = this.entityInfo.getEntityClass()
                                                  .getDeclaredField(entry.getKey());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
